package com.yundingai.interceptor;

import com.yundingai.context.UserContext;
import com.yundingai.exception.BusinessException;
import com.yundingai.utils.JwtUtil;
import com.yundingai.utils.RedisUtils;
import com.yundingai.vm.constant.RedisConstant;
import com.yundingai.vm.enums.ResultStatusEnum;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.IOException;

/**
 * 用于验证用户Token的有效性
 */
@Slf4j
@Component
public class AuthInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisUtils redisUtils;

    @Override
    //在控制器方法执行前进行Token验证
    public boolean preHandle(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) throws IOException {
        // 1. 从请求头获取Token
        String token = request.getHeader("Authorization");
        log.info("token:{}", token);
        // 2.验证Token是否存在且有效
        if (token == null) {
            log.info("token不存在");
            throw new BusinessException(ResultStatusEnum.NEED_LOGIN);
        }
        //3. 处理Token前缀（如"Bearer "）
        token = JwtUtil.handlePrefix(token);
        //4. 从Token中解析用户ID
        Integer userId = JwtUtil.getUserId(token);
        //5. 验证Token是否存在
        if (!redisUtils.keyIsExist(RedisConstant.USER_LOGIN_KEY + userId)) {
            log.info("token已过期");
            throw new BusinessException(ResultStatusEnum.NEED_LOGIN);
        }
        //6. 单设备登录验证
        if (!redisUtils.get(RedisConstant.USER_LOGIN_KEY + userId).equals(token)) {
            log.info("异地登录");
            throw new BusinessException(ResultStatusEnum.USER_LOGIN_OTHER_DEVICE);

        }
        log.info("find:{}", redisUtils.get(RedisConstant.USER_LOGIN_KEY + userId));
        
        // 将用户ID放入上下文
        UserContext.setUserId(userId);
        log.info("用户ID已放入上下文: {}", userId);
        
        //延期有问题
//        redisUtils.expire(RedisConstant.USER_LOGIN_KEY + userId, RedisConstant.TOKEN_EXPIRE);
        return true;
    }
    
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 清理ThreadLocal，防止内存泄漏
        UserContext.clear();
        log.debug("用户上下文已清理");
    }
}